package com.tbit.uqbike.client.service.impl;

import cn.hutool.core.util.StrUtil;
import com.tbit.uqbike.client.constant.AccountSmsModelConstant;
import com.tbit.uqbike.client.constant.BrandConstant;
import com.tbit.uqbike.client.constant.MachineAlarmConstant;
import com.tbit.uqbike.client.constant.SysConstant;
import com.tbit.uqbike.client.dao.core.MachineLoseDao;
import com.tbit.uqbike.client.dao.log.MachineAlarmLogDao;
import com.tbit.uqbike.client.exception.BaseException;
import com.tbit.uqbike.client.pojo.*;
import com.tbit.uqbike.client.remote.map.TXHttpClient;
import com.tbit.uqbike.client.remote.sms.AliSms;
import com.tbit.uqbike.client.remote.sms.ClzySmsAuthUtil;
import com.tbit.uqbike.client.remote.sms.apistore.ApiStoreMsgUtils;
import com.tbit.uqbike.client.service.*;
import com.tbit.uqbike.client.util.DateTimeUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author: ShiGuang
 * @create: 2021-12-15 10:37
 * @description: 丢失车辆服务实现类
 */
@Service
public class MachineLoseServiceImpl implements MachineLoseService {

    private final static org.apache.logging.log4j.Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);

    @Autowired
    private MachineLoseDao machineLoseDao;
    @Autowired
    private MachineService machineService;
    @Autowired
    private MachineAlarmService machineAlarmService;
    @Autowired
    private MachineAlarmLogDao machineAlarmLogDao;
    @Autowired
    private SmsAuthConfigService smsAuthConfigService;
    @Autowired
    private CalibrateService calibrateService;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private AccountSmsModelService accountSmsModelService;


    /**
     * 发现丢失车俩发送报警信息
     *
     * @param machineNOList 设备编号
     * @param lo            经度
     * @param la            纬度
     * @param mapType       地图类型
     * @param accountId     品牌id
     */
    @Override
    public void sendMessage(List<String> machineNOList, Double lo, Double la, Integer mapType, Integer accountId) {
        // 经纬度转换
        Point point;
        point = new Point(lo, la);
        point = calibrateService.calibrate(point, mapType, SysConstant.ORIGINAL);
        // 把经纬度转换为具体的地点
        String address = TXHttpClient.getAddress(lo, la);

        for (String machineNO : machineNOList) {
            // 根据车辆编号获取区域id
            Machine machine = machineService.getByMachineNO(machineNO);
            if (machine == null) {
                continue;
            }
            Integer adAccountId = machine.getAccountId();
            // 根据区域id查询是否开启了车辆预警配置
            MachineAlarm machineAlarm = machineAlarmService.getByAccountId(adAccountId);
            if (machineAlarm == null || machineAlarm.getMachineLoseSwitch() == 0) {
                return;
            }
            // 从redis中获取丢失车辆信息
            List<MachineLose> machineLoseList = cacheService.getMachineLose(adAccountId);
            if (machineLoseList == null || machineLoseList.size() == 0) {
                return;
            }
            // 判断上传过来的车辆是否为丢失车辆
            for (MachineLose machineLose : machineLoseList) {
                boolean flag = StringUtils.equals(machineNO, machineLose.getMachineNO());
                if (flag) {
                    // 记录日志内容
                    MachineAlarmLog machineAlarmLog = new MachineAlarmLog();
                    machineAlarmLog.setAccountId(adAccountId);
                    machineAlarmLog.setUserCode(machineLose.getUserCode());
                    machineAlarmLog.setAlarmType(MachineAlarmConstant.MACHINE_ALARM_DSCL_TYPE);
                    machineAlarmLog.setAlarmTime(DateTimeUtil.getNowTime());
                    machineAlarmLog.setRemark("发现丢失车辆，Point=" + point.toString() + "，位置：" + address);

                    // 发现丢失车辆，上报运维人员
                    // 查看预警日志是否短期内已经发送过短信
                    List<MachineAlarmLog> machineAlarmLogs = machineAlarmLogDao.getByUserCode(machineLose.getUserCode());
                    if (machineAlarmLogs != null && machineAlarmLogs.size() > 0) {
                        for (MachineAlarmLog machineAlarmLog1 : machineAlarmLogs) {
                            String remark = machineAlarmLog1.getRemark();
                            // 只有发送过短信的才不会二次发送
                            if (remark == null || !remark.contains("Point")) {
                                // 没有发送过短信，发送短信
                                sendSMS(machineAlarm, adAccountId, machineLose.getUserCode(), address);
                                machineAlarmLogDao.insert(machineAlarmLog);
                            }
                        }
                    } else {
                        sendSMS(machineAlarm, accountId, machineLose.getUserCode(), address);
                        machineAlarmLogDao.insert(machineAlarmLog);
                    }
                }

            }
        }
    }

    /**
     * 发送短信
     *
     * @param machineAlarm
     * @param accountId    品牌id
     * @param userCode
     * @param address
     */
    @Transactional(rollbackFor = Exception.class)
    void sendSMS(MachineAlarm machineAlarm, Integer accountId, String userCode, String address) {
        String alarmPhone = machineAlarm.getAlarmPhone();
        if (StrUtil.isNotBlank(alarmPhone)) {
            // 首先获取运维人员号码
            String[] phones = alarmPhone.split("\\,");
            // 兼容创蓝发送短信
            BrandRemoteConfig brandRemoteConfig = cacheService.getBrandRemoteConfig(accountId, BrandConstant.CLYZ_SMS);
            // 判断是否配置了创蓝
            if (brandRemoteConfig != null && brandRemoteConfig.getParamKV().contains("account=") && brandRemoteConfig.getParamKV().contains("&password=")) {
                // 存储格式为account=xxx&password=xxx
                if (brandRemoteConfig.getParamKV().contains("account=") && brandRemoteConfig.getParamKV().contains("&password=")) {
                    String key = brandRemoteConfig.getParamKV();
                    String[] strings = key.split("&");
                    String account = strings[0].substring(strings[0].indexOf("=") + 1);
                    String password = strings[1].substring(strings[1].indexOf("=") + 1);
                    for (String phone : phones) {
                        // 获取短信发送结果
                        Boolean result = ClzySmsAuthUtil
                                .sendSms(account, password, "资产安全预警提醒：发现丢失车辆：位置" + address, phone);
                        if (!result) {
                            throw new BaseException("-101", "系统异常");
                        }
                    }
                } else {
                    throw new BaseException("-103", "系统配置错误");
                }
            }
            // 使用寻程或者阿里云发送短信
            else {
                // 获取短信模板
                AccountSmsModel accountSmsModel = accountSmsModelService.getByAccountIdAndType(accountId, AccountSmsModelConstant.SMS_ZC);
                if (accountSmsModel != null) {
                    // 兼容短信验证码数据库配置，支持寻程和阿里云发送发送
                    SmsAuthConfig smsAuthConfig = smsAuthConfigService.getByAccountId(accountId);
                    if (smsAuthConfig != null) {
                        // from为0代表寻程，1代表阿里云
                        if (smsAuthConfig.getFrom() == 0) {
                            // 发送短信
                            for (String phone : phones) {
                                ApiStoreMsgUtils.sendLostMachineAlarm(phone, userCode, smsAuthConfig.getSmsCodeKey(), accountSmsModel.getModelId(), address);
                            }
                        } else if (smsAuthConfig.getFrom() == 1) {
                            /**兼容阿里云存放秘钥，用分号分割*/
                            String[] strings = smsAuthConfig.getSmsCodeKey().split(";");
                            for (String phone : phones) {
                                AliSms.sendLostMachineAlarm(strings[0], strings[1], smsAuthConfig.getRemark(), smsAuthConfig.getSmsModelId(), phone, userCode, address);
                            }
                        }
                    }
                }


            }
        }
    }
}